package com.dingwen.treasure.business.controller;

import com.dingwen.treasure.base.controller.BaseViewController;
import com.dingwen.treasure.base.pojo.vo.Result;
import com.dingwen.treasure.business.component.AsyncComponent;
import com.dingwen.treasure.model.entity.mybatisplus.SysUser;
import com.dingwen.treasure.mybatisplus.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * 　AsyncController </br>
 * <p>使用自带对线程池弊端：</p>
 * <ul>
 *     <li>newCachedThreadPool: 非核心线程与任务1对1无穷大，导致CPU 100% 问题</li>
 *     <li>newSingleThreadScheduledExecutor： 核心线程1，非核心线程无穷大，CPU 100%</li>
 *     <li>newFixedThreadPool: 指定线程（核心）数，无限队列，OOM </li>
 *     <li>newSimpleThreadPool: 只有一个线程，无限队列，OOM </li>
 * </ul>
 * 　@author dingwen
 * 　@date 2022/5/13$
 */
@Api(tags = "线程池，异步任务综合")
@RestController
@Slf4j
@RequestMapping("async")
public class AsyncController implements BaseViewController {

    /**
     * 异步任务组件
     */
    @Resource
    private AsyncComponent asyncComponent;

    /**
     * asyncExecutor
     */
    @Resource
    private ThreadPoolTaskExecutor asyncExecutor;

    /**
     * 用户服务
     */
    @Resource
    private SysUserService sysUserService;

    /**
     * 异步任务测试1
     *
     * @return Result result
     */
    @ApiOperation("异步任务测试1")
    @GetMapping("one")
    public void testOne() {
        asyncComponent.taskOne();
    }

    /**
     * 异步任务测试2
     *
     * @return Result result
     */
    @ApiOperation("异步任务测试2")
    @GetMapping("two")
    public void testTwo() {
        asyncComponent.taskTwo();
    }

    /**
     * 测试线程池提供异步任务
     *
     * @return {@link Result}
     */
    @ApiOperation("测试线程池提供异步任务")
    @GetMapping("execute")
    public void testThree() {
        asyncExecutor.execute(() -> sysUserService.save(SysUser.builder().account("ding").build()));
    }

    /**
     * 测试线程池提供异步任务
     *
     * @return {@link Result}
     */
    @ApiOperation("测试线程池提供异步任务")
    @GetMapping("submit")
    public Result<SysUser> testFour() throws ExecutionException, InterruptedException {
        Future<SysUser> sysUserFuture = asyncExecutor.submit(() -> sysUserService.getById(1L));
        return success(sysUserFuture.get());
    }


}
